package rank;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class SpeRedisLeaderboardService {

    private static final String LEADERBOARD_SCORE_KEY = "game_score_leaderboard";

    private final JedisPool jedisPool;


    public SpeRedisLeaderboardService(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }


    public void updateScore(String playerId, int score, int oldscore) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.sadd(LEADERBOARD_SCORE_KEY, String.valueOf(score));
            jedis.sadd(String.valueOf(score), playerId);
            jedis.srem(String.valueOf(oldscore), playerId);
        }
    }


    public RankInfo getPlayerRank(String playerId, int score) {
        try (Jedis jedis = jedisPool.getResource()) {
            Set<String> members = jedis.smembers(LEADERBOARD_SCORE_KEY);
            List<Integer> integerList = members.stream()
                    .map(Integer::parseInt).sorted((a, b) -> b - a)
                    .collect(Collectors.toList());

            for (int i = 1; i < integerList.size(); i++) {
                if (integerList.get(i - 1) == score) {
                    return new RankInfo(playerId, i, score);
                }
            }
        }
        return null;
    }

    public List<RankInfo> getTopN(int n) {
        try (Jedis jedis = jedisPool.getResource()) {
            Set<String> members = jedis.smembers(LEADERBOARD_SCORE_KEY);
            List<Integer> integerList = members.stream()
                    .map(Integer::parseInt).sorted((a, b) -> b - a)
                    .collect(Collectors.toList());
            List<RankInfo> infos = new ArrayList();
            for (int i = 1; i < integerList.size(); i++) {
                Set<String> playerMembers = jedis.smembers(String.valueOf(integerList.get(i - 1)));
                for (String playerId : playerMembers) {
                    infos.add(new RankInfo(playerId, i, integerList.get(i - 1)));
                }
            }
        }
        return null;
    }

}
